package org.lc.stk.security.service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.lc.stk.dao.UserRepository;
import org.lc.stk.model.user.User;
import org.lc.stk.security.util.PermissionConverter;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 自定义用户详情服务
 * 负责加载用户信息并构建Spring Security所需的UserDetails对象
 */
@Service
public class CustomUserDetailsService implements UserDetailsService {

    private final UserRepository userRepository;

    public CustomUserDetailsService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    @Transactional(readOnly = true)
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("用户不存在: " + username));

        List<SimpleGrantedAuthority> authorities = new ArrayList<>();

        // 添加角色权限
        authorities.addAll(user.getRoles().stream()
                .map(userRole -> new SimpleGrantedAuthority("ROLE_" + userRole.getRole().getName()))
                .collect(Collectors.toList()));

        // 添加资源级权限
        if (user.getRoles() != null) {
            user.getRoles().forEach(userRole -> {
                userRole.getRole().getPermissions().forEach(permission -> {
                    authorities.addAll(PermissionConverter.convertToAuthorities(permission));
                });
            });
        }

        return org.springframework.security.core.userdetails.User
                .withUsername(user.getUsername())
                .password(user.getPassword())
                .authorities(authorities)
                .build();
    }
}